(function($){
	var defaults = {
		lineColor:"blue",
		lineWidth:4,
		flickerTime:500,
		moveTime:500,
		rate:1,
		msgCss:{
			width:42,
			height:20,
			align:"center",
			"background-color":"#5cb85c",
			overflow:"hidden"
		}
	};
	var viewCss = {
		overflow:"hidden",
		position:"relative"
	};
	var setting;
	var ctx;
	var img = new Image();
	var setSize = function(obj){
		if(setting.width!=undefined){
			obj.css("width",setting.width);
		}else{
			obj.css("width",img.width);
		}
		if(setting.height!=undefined){
			obj.css("height",setting.height);
		}else{
			obj.css("height",img.height);
		}
	};
	var drawMap = function(){
		var x = Math.round(img.width*setting.rate);
		var y = Math.round(img.height*setting.rate);
		$("#_cvs").attr("width",x);
		$("#_cvs").attr("height",y);
		ctx = $("#_cvs")[0].getContext("2d");
		ctx.drawImage(img,0,0,x,y);
	};
	var placeMap = function(){
		var map = $("#_map");
		map.css({
			width:map.children("#_cvs").width(),
			height:map.children("#_cvs").height()
		});
		if(map.width()>map.parent().width()){
			map.css({
				position:"absolute",
				left:0,
				top:0
			});
		}else{
			var x = Math.round((setting.width-map.width())/2);
			map.css({
				position:"absolute",
				left:x,
				top:0
			});
		}
	}
	var putPoint = function(data){
		var map = $("#_map");
		var x = Math.round(data.px*setting.rate);
		var y = Math.round(data.py*setting.rate);
		map.append("<div id='_index"+data.id+"' style='position:absolute;left:"+x+"px;top:"+y+"px;'><img src='"+root+"/resources/jmap/images/"+data.pic+"' style='margin:0px auto 5px;display:block;' /><div style='width:42px;height:0px;'></div></div>");
		map.children("#_index"+data.id).data("data",data);
		if(data.msg!=undefined){
			map.children("#_index"+data.id).children("div").css(setting.msgCss).text(data.msg);
			if(data.color!=undefined){
				map.children("#_index"+data.id).children("div").css("background-color",data.color);
			}
		}
		if(setting.hover.overfn!=undefined&&setting.hover.outfn!=undefined){
			map.children("#_index"+data.id).hover(setting.hover.overfn,setting.hover.outfn);
		}
		if(setting.dblclickfn!=undefined){
			map.children("#_index"+data.id).css("cursor","pointer").dblclick(setting.dblclickfn);
		}
	};
	var putPoints = function(arr){
		var map = $("#_map");
		mapWidth = map.width();
		mapHeight = map.height();
		map.children("div").remove();
		for(i=0;i<arr.length;i++){
			putPoint(arr[i]);
		}
	};
	var drawLine = function(x1,y1,x2,y2){
		var r = 35;
		var lx1,ly1,lx2,ly2;
		if(x1 != x2){
			var rad = Math.atan2(y2-y1,x2-x1);
			lx1 = Math.round(x1+r*Math.cos(rad));
			ly1 = Math.round(y1+r*Math.sin(rad));
			lx2 = Math.round(x2-r*Math.cos(rad));
			ly2 = Math.round(y2-r*Math.sin(rad));
		}else{
			lx1 = x1;
			lx2 = x2;
			if(y1<y2){
				ly1 = y1+r;
				ly2 = y2-r;
			}else{
				ly1 = y1-r;
				ly2 = y2+r;
			}
		}
		ctx.strokeStyle = setting.lineColor;
		ctx.lineWidth = setting.lineWidth;
		ctx.beginPath();
		ctx.moveTo(lx1+0.6*r,ly1+0.6*r);
		ctx.lineTo(lx2+0.6*r,ly2+0.6*r);
		ctx.stroke();
	};
	var viewChange = function(x,y){
		var map = $("#_map");
		var center = {
			x:Math.round(setting.width/2),
			y:Math.round(setting.height/2)
		}
		var offsetx,offsety;
		offsetx = center.x-x;
		offsety = center.y-y;
		if(offsetx>0)offsetx=0;
		if(offsetx<setting.width-map.width())offsetx=setting.width-map.width();
		if(map.width()<=map.parent().width()){
			offsetx = map.position().left;
		}
		if(offsety>0)offsety=0;
		if(offsety<setting.height-map.height())offsety=setting.height-map.height();
		if(map.height()<=map.parent().height()){
			offsety = map.position().top;
		}
		map.stop(true).animate({
				left:offsetx,
				top:offsety
		},setting.moveTime);
	};
	var flicker = function(id){
		var map = $("#_map");
		taskId = setInterval(function(){
			map.children("#_index"+id).css("display","none");
			setTimeout(function(){
				map.children("#_index"+id).css("display","block");
			},setting.flickerTime);
		},2*setting.flickerTime);
		setTimeout(function(){
			clearInterval(taskId);
		},5.5*setting.flickerTime);
	};
	var drawtk = function(arr){
		var id = arr.shift();
		var oldPoint = $("#_index"+id).position();
		var newPoint = $("#_index"+arr[0]).position();
		viewChange(newPoint.left,newPoint.top);
		drawLine(oldPoint.left,oldPoint.top,newPoint.left,newPoint.top);
		flicker(arr[0]);
		if(arr.length>1){
			setTimeout(function(){
				drawtk(arr);
			},6*setting.flickerTime);
		}
	};
	var changePic = function(data){
		var src = $("#_map").children("#_index"+data.id).children("img").attr("src");
		var p = src.substr(src.lastIndexOf("/")+1);
		if(p != data.pic)
		$("#_map").children("#_index"+data.id).children("img").attr("src",root+"/resources/jmap/images/"+data.pic).parent().children("div").css("background-color",data.color);
	}
	var changeMsg = function(data){
		$("#_map").children("#_index"+data.id).children("div").css(setting.msgCss).text(data.msg);
	};
	var drag = function(){
		$("#_map").parent().mousedown(function(e){
			var data = {};
			data.x = e.pageX;
			data.y = e.pageY;
//			data.mapX = $("#_map").position().left;
//			data.mapY = $("#_map").position().top;
			$(document).data("data",data);
			$("body").css("cursor","move");
		});
		$(document).mousemove(function(e){
			var data = $(document).data("data");
			if(data!=null){
				var map = $("#_map");
//				var offsetx = data.mapX+e.pageX-data.x;
//				var offsety = data.mapY+e.pageY-data.y;
				var offsetx = map.position().left+e.pageX-data.x;
				var offsety = map.position().top+e.pageY-data.y;
				data.x = e.pageX;
				data.y = e.pageY;
				if(offsetx>0)offsetx=0;
				if(offsetx<setting.width-map.width())offsetx=setting.width-map.width();
				if(map.width()<=map.parent().width())offsetx = map.position().left;
				if(offsety>0)offsety=0;
				if(offsety<setting.height-map.height())offsety=setting.height-map.height();
				if(map.height()<=map.parent().height())offsety = map.position().top;
				map.css("left",offsetx).css("top",offsety);
			}
		});
		$(document).mouseup(function(){
			$(document).removeData("data");
			$("body").css("cursor","auto");
		});
	};
	$.fn.Jmapinit=function(){
		var params = arguments[0];
		return this.each(function(){
			var $this = $(this);
			setting = $.extend({},defaults,params);
			$this.html("<div id='_map'><canvas id='_cvs'></canvas></div>");
			$("#_map").parent().parent().append("<div id='_msgpsn'></div>");
			$this.css(viewCss);
			img.onload = function(){
				setSize($this);
				drawMap();
				placeMap();
				putPoints(setting.data);
				drag();
			};
			img.src = setting.img;
		});
	};
	$.fn.Jmaptrack = function(){
		var params = arguments[0];
		return this.each(function(){
			function execute(){
				if(params.length>1){
					var p = $("#_index"+params[0]).position();
					viewChange(p.left,p.top);
					setTimeout(function(){
						var arr = [];
						arr = params.concat();
						drawtk(arr);
					},1200);
				}
			}
			var taskid = setInterval(function(){
				if(img.complete){
					execute();
					clearInterval(taskid);
				}
			},20);
		});
	};
	$.fn.Jmapadd = function(){
		var params = arguments[0];
		return this.each(function(){
			setting.data.push(params);
			putPoint(params);
			var x = Math.round(params.px*setting.rate);
			var y = Math.round(params.py*setting.rate);
			viewChange(x,y);
		});
	};
	$.fn.Jmapcgpic = function(){
		var params = arguments[0];
		return this.each(function(){
			changePic(params);
		});
	};
	$.fn.Jmapcgmsg = function(){
		var params = arguments[0];
		return this.each(function(){
			changeMsg(params);
		});
	};
	$.fn.Jmapclear = function(){
		var params = arguments[0];
		return this.each(function(){
			drawMap();
		});
	};
	$.fn.Jmapscale = function(){
		var params = arguments[0];
		return this.each(function(){
			setting.rate = params;
			drawMap();
			placeMap();
			putPoints(setting.data);
		});
	}
})(jQuery);
